package net.sshiffon.grittyish;

import java.awt.Dimension;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import com.jcraft.jsch.ChannelShell;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.wittams.gritty.Questioner;
import com.wittams.gritty.Tty;
import org.apache.log4j.Logger;

public class SshiffonTty implements Tty {
    private static Logger logger = Logger.getLogger(SshiffonTty.class);
	private InputStream in = null;
	private OutputStream out = null;
	private Session session;
	private ChannelShell channel;
	private String name;

	private Dimension pendingTermSize;
	private Dimension pendingPixelSize;

	public SshiffonTty(String name, Session session){
		this.session = session;
                this.name = name;
	}

	public void resize(Dimension termSize, Dimension pixelSize) {
			pendingTermSize = termSize;
			pendingPixelSize = pixelSize;
			if(channel != null) resizeImmediately();
	}

	private void resizeImmediately() {
            //logger.debug("called resizeImmediately");
		if(pendingTermSize != null && pendingPixelSize != null){
			channel.setPtySize(pendingTermSize.width,pendingTermSize.height, pendingPixelSize.width, pendingPixelSize.height);
			pendingTermSize = null;
			pendingPixelSize = null;
		}
	}


	public void close(){
		if (session != null) {
			session.disconnect();
			session = null;
			channel = null;
			in = null;
			out = null;
		}
	}

	public boolean init(Questioner q)
        {
            try {
                channel = (ChannelShell) session.openChannel("shell");
                in = channel.getInputStream();
                out = channel.getOutputStream();

                //channel.setXForwarding(true);
                channel.connect();
                logger.debug("resizing during init!");
                resizeImmediately();
                return true;
            } catch (final IOException e) {
                //SshiffonTty.showMessage(e.getMessage());
                logger.error("Error opening channel",e);
                    return false;
            } catch (final JSchException e) {
                //SshiffonTty.showMessage(e.getMessage());
                logger.error("Error opening session or channel",e);
                return false;
            }
	}


        public Session getSession()
        {
            return session;
        }

	public String getName(){
		return name;
	}

	public int read(byte[] buf, int offset, int length) throws IOException{
		if(in != null)
		{
			return in.read(buf, offset, length);
		} else {
			logger.error("InputStream is null");
			return -1;
			//throw new IOException("InputStream is null");
		}
	}

	public void write(byte[] bytes) throws IOException{
		if(out!=null)
		{
			out.write(bytes);
			out.flush();
		} else {
			logger.error("OutputStream is null");
			//throw new IOException("OutputStream is null");
		}
	}

}
